package com.ld.common.util.security;

import java.util.LinkedHashMap;
import java.util.Map;

import com.ld.shieldsb.common.composition.util.SecurityUtil;
import com.ld.shieldsb.common.core.model.Result;
import com.ld.shieldsb.common.core.reflect.ClassUtil;
import com.ld.shieldsb.common.core.util.PathUtil;
import com.ld.shieldsb.common.core.util.StringUtils;
import com.ld.shieldsb.common.web.util.ConfigurationFileUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 牵扯到加密解密的统一在此处理，读操作的修改密钥不影响，写操作则需要重新导出数据，注意需要在项目启动后执行init方法初始化所有加密相关的密钥
 * 
 * @ClassName ProjectSecurityUtil
 * @author <a href="mailto:donggongai@126.com" target="_blank">吕凯</a>
 * @date 2019年8月2日 下午3:08:13
 *
 */
@Slf4j
public class ProjectSecurityUtil {
    private static SecurityKey securityKey;
    public static final String PREFERENCE_FILE_PREFIX = "serurity"; // 配置信息文件名称

    public static final String SIMPLE_SECRET_KEY_R = "SIMPLE_SECRET_KEY_R";
    public static final String SIMPLE_SECRET_KEY_RW = "SIMPLE_SECRET_KEY_RW";
    public static final String DES_SECRET_KEY = "DES_SECRET_KEY";
    public static final String EOR_SECRET_KEY_R = "EOR_SECRET_KEY_R";
    public static final String USER_HOME = "user.home";
    public static final String USER_DIR = "user.dir";

    private static Map<String, String> preferenceMap;

    /**
     * 初始化SecurityKey对象
     * 
     * @Title init
     * @author 吕凯
     * @date 2019年8月2日 下午4:46:39
     * @param security
     * @return boolean
     */
    public static boolean load(SecurityKey security) {
        securityKey = security;
        SecurityUtil.SIMPLE_SECRET_KEY_RW = securityKey.getSimpleKeyRW(); // 工具类赋值
        SecurityUtil.SIMPLE_SECRET_KEY_R = securityKey.getSimpleKeyR();
        SecurityUtil.DES_SECRET_KEY = securityKey.getDesKey();
        SecurityUtil.EOR_SECRET_KEY_R = securityKey.getQueryKey();
        try {
            Map<String, String> map = new LinkedHashMap<>();
            map.put(SIMPLE_SECRET_KEY_R, securityKey.getSimpleKeyR());
            map.put(SIMPLE_SECRET_KEY_RW, securityKey.getSimpleKeyRW());
            map.put(DES_SECRET_KEY, securityKey.getDesKey());
            map.put(EOR_SECRET_KEY_R, securityKey.getQueryKey() + "");
            map.put(USER_HOME, PathUtil.getUserHome());
            map.put(USER_DIR, PathUtil.getProjectPath());
            preferenceMap = map;
            savePreferenceModel(map);
        } catch (Exception e) {
            String msg = "设置文件出错！" + e.getMessage();
            log.error("", msg);
        }
        return true;
    }

    public static int getEorSecretKey() {
        String key = null;
        Map<String, String> model = getPreferenceMap();
        if (model != null) {
            key = model.get(EOR_SECRET_KEY_R);
        }
        if (key == null) {
            key = StringUtils.getRandomNum(6);
        }
        int result = ClassUtil.obj2int(key);
        if (result == 0) { // 字符可能被修改过
            result = ClassUtil.obj2int(StringUtils.getRandomNum(6));
        }
        return result;
    }

    public static String getSimpleSecretKeyR() {
        String key = null;
        Map<String, String> model = getPreferenceMap();
        if (model != null) {
            key = model.get(SIMPLE_SECRET_KEY_R);
        }
        if (key == null) {
            key = StringUtils.getRandomStr(6);
        }
        return key;
    }

    @SuppressWarnings("unchecked")
    public static Map<String, String> getPreferenceMap() {
        if (preferenceMap != null) {
            return preferenceMap;
        }
        // 不存在则查询文件
        preferenceMap = ConfigurationFileUtil.readObjFromConfigFile(PREFERENCE_FILE_PREFIX, Map.class);
        return null;
    }

    /**
     * 保存个人偏好设置
     * 
     * @Title savePreferenceModel
     * @author 吕凯
     * @date 2018年12月21日 下午1:16:21
     * @param model
     * @return Result
     */
    public static Result savePreferenceModel(Map<String, String> model) {
        return ConfigurationFileUtil.saveObj2ConfigFile(PREFERENCE_FILE_PREFIX, model);
    }

    public static SecurityKey getSecurityKey() {
        return securityKey;
    }

    /**
     * 
     * 简单加密，会保存的用此方法（DES，安全等级要求不高的情况）
     * 
     * @Title simpleWriteEncrypt
     * @param strIn
     *            字符串
     * @return
     * @throws Exception
     *             String
     */
    public static String simpleWriteEncrypt(String strIn) {
        return SecurityUtil.simpleWriteEncrypt(strIn);
    }

    /**
     * 
     * 简单解密，会保存的用此方法（DES，安全等级要求不高的情况）
     * 
     * @Title encryptIn
     * @param strIn
     *            字符串
     * @return
     * @throws Exception
     *             String
     */
    public static String simpleWriteDecrypt(String strIn) {
        return SecurityUtil.simpleWriteDecrypt(strIn);
    }

    /**
     * 
     * Des解密，可用于保存
     * 
     * @Title desDecrypt
     * @author 吕凯
     * @date 2019年8月22日 上午10:40:10
     * @param strIn
     * @return String
     */
    public static String desDecrypt(String strIn) {
        return SecurityUtil.desDecrypt(strIn);
    }

    /**
     * Des解密，可用于保存
     * 
     * @Title desEncrypt
     * @author 吕凯
     * @date 2019年8月22日 上午10:40:31
     * @param strIn
     * @return String
     */
    public static String desEncrypt(String strIn) {
        return SecurityUtil.desEncrypt(strIn);
    }

    /**
     * 
     * 简单加密，只读取的用此方法，注意可能保存的一定不能使用此方法（DES，安全等级要求不高的情况）
     * 
     * @Title simpleReadEncrypt
     * @author 吕凯
     * @date 2019年8月2日 下午4:59:01
     * @param strIn
     * @return String
     */
    public static String simpleReadEncrypt(String strIn) {
        return SecurityUtil.simpleReadEncrypt(strIn);
    }

    /**
     * 
     * 简单解密，只读取的用此方法，注意可能保存的一定不能使用此方法（DES，安全等级要求不高的情况）
     * 
     * @Title simpleReadDecrypt
     * @author 吕凯
     * @date 2019年8月2日 下午4:59:20
     * @param strIn
     * @return String
     */
    public static String simpleReadDecrypt(String strIn) {
        return SecurityUtil.simpleReadDecrypt(strIn);
    }

}
